#include <iostream>
#include <memory>

class test : public std::enable_shared_from_this<test> {
public:
    test () = default;
    virtual ~test () = default;
    std::shared_ptr<test> getptr() {
        //return std::shared_ptr<test>(this);
        return shared_from_this();
    }
    void print() {
        auto xx = shared_from_this();
        std::cout<<xx.use_count()<<std::endl;
    }

private:
    /* data */
};

int main(int argc, char **argv) {
    std::shared_ptr<int> sip = std::make_shared<int>(5);
    std::shared_ptr<int> sip2(sip);
    auto sip3 = sip2;
    std::cout<<"1:"<<sip.use_count()<<" 2:"<<sip2.use_count()<<"value:"<<*sip3<<std::endl;

    int* intp = new int(5);
    std::shared_ptr<int> sinp1(intp);
    std::shared_ptr<int> sinp2(intp);
    if (sinp1.get() == sinp2.get())
        std::cout<<"-1:"<<sinp1.use_count()<<"-2:"<<sinp2.use_count()<<" "<<*sinp1<<std::endl;

    std::shared_ptr<test> xx = std::make_shared<test>();
    std::cout<<"----------------"<<std::endl;
    std::cout<<xx.use_count()<<std::endl;
    auto mm = xx->getptr();
    std::cout<<xx.use_count()<<std::endl;
    xx->print();
    std::cout<<"----------------"<<std::endl;
    auto m1 = new(std::nothrow) test();
    auto sm1 = std::shared_ptr<test>(m1);
    std::cout<<sm1.use_count()<<std::endl;

    auto sm2 = m1->shared_from_this();
    std::cout<<sm1.use_count()<<std::endl;
    std::cout<<sm2.use_count()<<std::endl;

    return 0;
}
